import libtcodpy as libtcod

import console

import utils

SCALE = 8

RED = 0.75
GREEN = 1.25
BLUE = 1.75

class Effects(object):
    def __init__(self, root, log):
        self.root = root
        self.width, self.height = self.root.width, self.root.height
        im_width, im_height = self.root.width * SCALE, self.root.height * SCALE

        rand = libtcod.random_get_instance()

        log('Building effects.  This might take a while if this is the first run.')
        r = utils.read_noise('back_r.png', im_width, im_height, libtcod.Color(255, 0, 0), 
                             SCALE * 1.0, write=True, method=libtcod.noise_wavelet)
        log('Reticulating splines.')
        g = utils.read_noise('back_g.png', im_width, im_height, libtcod.Color(0, 255, 0), 
                             SCALE * 1.5, write=True, method=libtcod.noise_wavelet)
        log('Tuning up.')
        b = utils.read_noise('back_b.png', im_width, im_height, libtcod.Color(0, 0, 255),
                             SCALE * 2.0, write=True, method=libtcod.noise_wavelet)
        self.fields = (r, g, b)

        r_con = console.Console(self.width, self.height)
        g_con = console.Console(self.width, self.height)
        b_con = console.Console(self.width, self.height)
        self.con = (r_con, g_con, b_con)

        self.pos = [libtcod.random_get_float(rand, 0, self.width-1),
                    libtcod.random_get_float(rand, 0, self.height-1)]
        #self.vec = [libtcod.random_get_float(rand, 2, 6),
        #            libtcod.random_get_float(rand, 2, 6)]
        self.vec = [3.5, -2.0]

        self.last = 1.0
        self.disco = 0
        self.frame = 0
        self.pause = False

    def update(self, energy=1.0):
        if self.pause:
            if self.last >= BLUE:
                self.frame = 2
        else:
            self.last = energy

            self.pos[0] += self.vec[0] * energy**2
            self.pos[1] += self.vec[1] * energy**2

            if self.pos[0] < 0:
                self.pos[0] = 0.0
                self.vec[0] *= -1
            elif self.pos[0] >= self.width:
                self.pos[0] = float(self.width - 1)
                self.vec[0] *= -1

            if self.pos[1] < 0:
                self.pos[1] = 0.0
                self.vec[1] *= -1
            elif self.pos[1] >= self.height:
                self.pos[1] = float(self.height - 1)
                self.vec[1] *= -1

            for i in xrange(3):
                # Windows - This works.  It probably shouldn't, but it does. 
                #self.fields[i].blit_2x(self.con[i], 0, 0, int(self.pos[0]), int(self.pos[1]))

                # Linux - Doesn't fail assert checks under Ubuntu 8.04 w/ python 2.6 and 1.5.0
                #         (Also works for Windows as you would except)
                sx, sy = int(self.pos[0]), int(self.pos[1])
                w, h = sx + self.width, sy + self.height
                self.fields[i].blit_2x(self.con[i], 0, 0, sx, sy, w*2, h*2)

            if energy < RED:
                self.frame = 0
            elif energy < GREEN:
                self.frame = 1
            elif energy < BLUE:
                self.frame = 2
            else:  # DISCO
                self.disco += 0.5
                self.frame = int(self.disco + 0.5) % 3

        self.con[self.frame].blit(0, 0, self.width, self.height, self.root, 0, 0)

if __name__ == '__main__':
    import sys
    import time

    def log(msg):
        print msg

    libtcod.console_set_custom_font('fonts/arial10x10.png', libtcod.FONT_TYPE_GREYSCALE | libtcod.FONT_LAYOUT_TCOD)
    root = console.RootConsole(80, 30, 'Effect Test')
    libtcod.sys_set_fps(30)

    print "Building Fields..."
    start = time.time()
    effects = Effects(root, log)
    print "Done", (time.time() - start)

    print "Press ESC to exit."
    ix = 0
    energy = 1.0
    while root.open:
        effects.update(ix, energy=energy)
        root.print_left(0, root.height-1, libtcod.BKGND_SET, 'ENERGY: %.02f' % energy)
        root.print_fps()
        root.flush()
        key = root.check_for_keypress()
        if key.vk == libtcod.KEY_ESCAPE:
            break
        elif key.vk == libtcod.KEY_UP:
            energy = min(2.5, energy + 0.05)
        elif key.vk == libtcod.KEY_DOWN:
            energy = max(0.1, energy - 0.05)

        if energy < 0.5:
            ix = 0
        elif energy < 1.25:
            ix = 1
        elif energy < 1.75:
            ix = 2
        else: # WOW!
            ix = (ix + 1) % 3


